package com.yiban.demo.LoginUser.Controller;

import com.yiban.demo.Global.AOP.Annotation.LimitRequestDuration;
import com.yiban.demo.LoginUser.Entity.LoginUserPO;
import com.yiban.demo.LoginUser.Entity.LoginUserVO;
import com.yiban.demo.LoginUser.Entity.ROLE;
import com.yiban.demo.Global.Entity.ResponseEntity;
import com.yiban.demo.LoginUser.Service.LoginUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.HashMap;

//命名规范xxController

/**
 * 负责用户的各项信息比如注册登录修改密码
 */
@RestController
@RequestMapping("/User")
public class LoginUserController {
    @Autowired
    private LoginUserService loginUserService;
    public final static String userKeyInSession = "user";

    /**
     * 登录接口
     * @param loginUserVO 传入的用户信息
     * @param httpSession 当前session，如果成功写入session,键值对格式为"user":loginUserPO，即增加登陆状态
     * @return 如果验证成功返回用户信息，不成功用户信息为null且有错误信息{desc："请检查用户名和密码"}
     */
    @PostMapping(value = "/loginIn" ,consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<LoginUserVO> loginIn(@RequestBody @Validated LoginUserVO loginUserVO, HttpSession httpSession){
        if (httpSession.getAttribute("user") != null){
            return ResponseEntity.Failure("不要重复登陆");
        }
        final LoginUserPO loginUserPO = loginUserService.loginIn(loginUserVO);
        if (loginUserPO == null){
            return ResponseEntity.Failure("请检查用户名和密码");
        }
        httpSession.setAttribute(userKeyInSession, loginUserPO);
        return ResponseEntity.Success(loginUserService.transToLoginVo(loginUserPO));
    }

    /**
     * 获取当前用户
     * @param httpSession 当前session
     * @return 返回当前登录的用户信息
     */
    @GetMapping("/nowUser")
    public ResponseEntity<LoginUserVO> nowUser(HttpSession httpSession){
        return ResponseEntity.Success(loginUserService.transToLoginVo((LoginUserPO) httpSession.getAttribute("user")));
    }

    /**
     *
     * @param phoneNumber 电话号码
     * @return 是否发送成功
     */
    @PostMapping("/mailCode")
    public ResponseEntity<Boolean> mailCode(@RequestBody Integer phoneNumber){
        return loginUserService.sentMailCode(phoneNumber.toString())?ResponseEntity.Success(true):ResponseEntity.Failure("发送失败");
    }


    /**
     * 注册
     * @param loginUserVO 传入的用户信息
     * @param httpSession 当前session,如果成功写入session,键值对格式为"user":loginUserPO
     * @param mailCode 短信验证码 在header中以类似于”mail-code: code“的形式传入，必传
     * @param phone 从 /mailCode 接口的返回值中获取的id，在header中以类似于”phone-number:152******55“的形式传入，必传
     * @return 如果验证成功返回用户信息，不成功用户信息为null且有包含的错误信息{desc："注册失败，用户名重复"}
     */
    @PostMapping(value = "/register",consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<LoginUserVO> register(@RequestBody @Validated LoginUserVO loginUserVO,HttpSession httpSession,@RequestHeader("mail-code") String mailCode,@RequestHeader("phone-number")String phone){
        if (!loginUserService.checkMailCode(mailCode,phone)) {
            return ResponseEntity.Failure("短信验证码错误或已超时");
        }
        LoginUserPO loginUserPO = loginUserService.transToLoginPo(loginUserVO);
        loginUserPO.setPhoneNumber(phone);
        if (loginUserService.register(loginUserPO)) {
            httpSession.setAttribute(userKeyInSession,loginUserPO);
            loginUserVO.setRole(ROLE.USER.getName());
            return ResponseEntity.Success(loginUserVO);
        }
        return ResponseEntity.Failure("注册失败，用户名重复");
    }

    /**
     * 修改密码
     * @param passwords 包含老密码和新密码的键值对,老密码对应键为"oldPassword",新密码为"newPassword"
     * @param httpSession 当前session,如果修改成功那么session中的loginUserPO的password也会被修改
     * @return 如果成功返回true;
     *         两个密码只要存在一个空返回包含{desc："新旧密码存在为空"}的错误信息;
     *         如果密码就错误返回一个包含{desc:"旧密码错误"}的错误信息
     */
    @PutMapping(value = "/password",consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Boolean> modifyPassword(@RequestBody HashMap<String,String> passwords,
                                                  HttpSession httpSession){
        String oldPassword = passwords.get("oldPassword");
        String newPassword = passwords.get("newPassword");

        if (oldPassword==null || newPassword == null){
            return ResponseEntity.Failure("新旧密码存在为空");
        }
        final boolean isSuccess = loginUserService.modifyPassword((LoginUserPO) httpSession.getAttribute(userKeyInSession), oldPassword, newPassword);
        return isSuccess ? ResponseEntity.Success(true) : ResponseEntity.Failure("旧密码错误");
    }

    /**
     * 登出
     * @param httpSession 当前session。会移除键值对"user":loginUserPO，即清除登录状态
     * @return 默认为成功
     */
    @GetMapping("/loginOut")
    public ResponseEntity<Boolean> loginOut(HttpSession httpSession){
       // httpSession.removeAttribute(userKeyInSession);
        httpSession.invalidate();
        return ResponseEntity.Success(true);
    }

}
